using System;
using Microsoft.SPOT;
using System.Collections;

namespace KeyMaster
{
    class MorseCode
    {
        private ArrayList EncodedMessage = new ArrayList(); // The encoded message, I'd love to find a way to optimize this more as it's a total memory hog right now.

        /// <summary>
        /// We use this to define various signals: Dot, Dash, LetterGap, WordGap. The caller is expected to parse these into the desired transmission.
        /// The caller will receive integers matching those listed below.
        /// </summary>
        private enum signals
        {
            Dot = 1, // 1 tick of 'on'
            Dash = 2, // 3 ticks of 'on'
            LetterGap = 3, // 3 ticks of 'off' NOTE: In many cases you will want to set this to 2, since your parser should account for the gap between signals automatically.
            WordGap = 4, // 7 ticks of 'off' NOTE: In many cases you will want to set this to 6, since your parser should account for the gap between signals automatically.
        }

        /// <summary>
        /// Constructor for MorseCode, expects an uncoded message. This message is swiftly encoded.
        /// </summary>
        /// <param name="UncodedMessage">The message the caller wishes to encode into morse.</param>
        public MorseCode(string UncodedMessage)
        {
            // Move through the message and encode each string.
            for (int Step = 0; Step < UncodedMessage.Length; Step++)
            {
                //ToMorse(Message[Step]);
                ToMorse(UncodedMessage.ToLower()[Step]);
            }
        }

        /// <summary>
        /// Gets the signal for the desired position.
        /// We do *not* destructively move through the list in case the caller wishes to move through it again.
        /// </summary>
        /// <param name="Cell">The desired position.</param>
        /// <returns>The integer code for the desired signal.</returns>
        public int GetSignal(int Cell)
        {
            return (int)EncodedMessage[Cell];
        }

        /// <summary>
        /// Returns the number of signals to be processed. This is so the caller can move through with a loop.
        /// </summary>
        /// <returns>The number of signals to be processed.</returns>
        public int SignalCount()
        {
            return EncodedMessage.Count;
        }

        /// <summary>
        /// This hideous structure contains the data needed to encode our message into morse code.
        /// Accepts a letter and adds the neccessary steps onto our ArrayList Message.
        /// </summary>
        /// <param name="Letter">The letter to be encoded.</param>
        private void ToMorse(Char Letter)
        {
            switch (Letter)
            {
                case 'a':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'b':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'c':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'd':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'e':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'f':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'g':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'h':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'i':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'j':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'k':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'l':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'm':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'n':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'o':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'p':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'q':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'r':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 's':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 't':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'u':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'v':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'w':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'x':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'y':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case 'z':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case ' ':
                    EncodedMessage.Add(signals.WordGap);
                    break;

                case '1':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '2':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '3':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '4':
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '5':
                    for (int i = 0; i < 5; i++)
                    {
                        EncodedMessage.Add(signals.Dot);
                    }
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '6':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '7':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '8':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '9':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dot);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                case '0':
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.Dash);
                    EncodedMessage.Add(signals.LetterGap);
                    break;

                default:
                    Debug.Print("There was an error");
                    break;
            }
        }
    }
}
